{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LangChain + Function Calling + E2B Code Interpreter        \n",
    "**Powered by open-source [Code Interpreter SDK](https://github.com/e2b-dev/code-interpreter) by [E2B](https://e2b.dev/docs)**\n",
    "\n",
    "E2B's code interpreter SDK quickly creates a secure cloud sandbox powered by [Firecracker](https://github.com/firecracker-microvm/firecracker).\n",
    "\n",
    "Inside this sandbox is a running Jupyter server that the LLM can use."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 1: Install dependencies\n",
    "\n",
    "We start by install the [E2B code interpreter SDK](https://github.com/e2b-dev/code-interpreter) and [LangChain Python SDK](https://console.groq.com/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: e2b-code-interpreter in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (0.0.3)\n",
      "Requirement already satisfied: langchain in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (0.1.16)\n",
      "Requirement already satisfied: langchainhub in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (0.1.15)\n",
      "Requirement already satisfied: langchain-openai in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (0.1.4)\n",
      "Requirement already satisfied: e2b>=0.14.11 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b-code-interpreter) (0.15.0)\n",
      "Requirement already satisfied: pydantic<3,>1 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b-code-interpreter) (2.7.1)\n",
      "Requirement already satisfied: websocket-client<2.0.0,>=1.7.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b-code-interpreter) (1.8.0)\n",
      "Requirement already satisfied: PyYAML>=5.3 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (6.0.1)\n",
      "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (2.0.29)\n",
      "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (3.9.5)\n",
      "Requirement already satisfied: dataclasses-json<0.7,>=0.5.7 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (0.6.4)\n",
      "Requirement already satisfied: jsonpatch<2.0,>=1.33 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (1.33)\n",
      "Requirement already satisfied: langchain-community<0.1,>=0.0.32 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (0.0.34)\n",
      "Requirement already satisfied: langchain-core<0.2.0,>=0.1.42 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (0.1.46)\n",
      "Requirement already satisfied: langchain-text-splitters<0.1,>=0.0.1 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (0.0.1)\n",
      "Requirement already satisfied: langsmith<0.2.0,>=0.1.17 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (0.1.51)\n",
      "Requirement already satisfied: numpy<2,>=1 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (1.26.4)\n",
      "Requirement already satisfied: requests<3,>=2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (2.31.0)\n",
      "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain) (8.2.3)\n",
      "Requirement already satisfied: types-requests<3.0.0.0,>=2.31.0.2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchainhub) (2.31.0.20240406)\n",
      "Requirement already satisfied: openai<2.0.0,>=1.10.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain-openai) (1.23.6)\n",
      "Requirement already satisfied: tiktoken<1,>=0.5.2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain-openai) (0.6.0)\n",
      "Requirement already satisfied: aiosignal>=1.1.2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
      "Requirement already satisfied: attrs>=17.3.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (23.2.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.1)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.5)\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.4)\n",
      "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (3.21.1)\n",
      "Requirement already satisfied: typing-inspect<1,>=0.4.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (0.9.0)\n",
      "Requirement already satisfied: aenum>=3.1.11 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b>=0.14.11->e2b-code-interpreter) (3.1.15)\n",
      "Requirement already satisfied: jsonrpcclient>=4.0.3 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b>=0.14.11->e2b-code-interpreter) (4.0.3)\n",
      "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b>=0.14.11->e2b-code-interpreter) (2.9.0.post0)\n",
      "Requirement already satisfied: typing-extensions>=4.8.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b>=0.14.11->e2b-code-interpreter) (4.11.0)\n",
      "Requirement already satisfied: urllib3>=1.25.3 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b>=0.14.11->e2b-code-interpreter) (2.2.1)\n",
      "Requirement already satisfied: websockets>=11.0.3 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from e2b>=0.14.11->e2b-code-interpreter) (12.0)\n",
      "Requirement already satisfied: jsonpointer>=1.9 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from jsonpatch<2.0,>=1.33->langchain) (2.4)\n",
      "Requirement already satisfied: packaging<24.0,>=23.2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langchain-core<0.2.0,>=0.1.42->langchain) (23.2)\n",
      "Requirement already satisfied: orjson<4.0.0,>=3.9.14 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from langsmith<0.2.0,>=0.1.17->langchain) (3.10.1)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from openai<2.0.0,>=1.10.0->langchain-openai) (4.3.0)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from openai<2.0.0,>=1.10.0->langchain-openai) (1.9.0)\n",
      "Requirement already satisfied: httpx<1,>=0.23.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from openai<2.0.0,>=1.10.0->langchain-openai) (0.27.0)\n",
      "Requirement already satisfied: sniffio in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from openai<2.0.0,>=1.10.0->langchain-openai) (1.3.1)\n",
      "Requirement already satisfied: tqdm>4 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from openai<2.0.0,>=1.10.0->langchain-openai) (4.66.2)\n",
      "Requirement already satisfied: annotated-types>=0.4.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from pydantic<3,>1->e2b-code-interpreter) (0.6.0)\n",
      "Requirement already satisfied: pydantic-core==2.18.2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from pydantic<3,>1->e2b-code-interpreter) (2.18.2)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from requests<3,>=2->langchain) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from requests<3,>=2->langchain) (3.7)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from requests<3,>=2->langchain) (2024.2.2)\n",
      "Requirement already satisfied: regex>=2022.1.18 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from tiktoken<1,>=0.5.2->langchain-openai) (2024.4.16)\n",
      "Requirement already satisfied: httpcore==1.* in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from httpx<1,>=0.23.0->openai<2.0.0,>=1.10.0->langchain-openai) (1.0.5)\n",
      "Requirement already satisfied: h11<0.15,>=0.13 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai<2.0.0,>=1.10.0->langchain-openai) (0.14.0)\n",
      "Requirement already satisfied: six>=1.5 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from python-dateutil>=2.8.2->e2b>=0.14.11->e2b-code-interpreter) (1.16.0)\n",
      "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/valenta.and.thomas/Developer/e2b-cookbook/.venv/lib/python3.11/site-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain) (1.0.0)\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install e2b_code_interpreter==1.0.0 langchain langchainhub langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 2: Define API keys, prompt, and tools\n",
    "\n",
    "Let's define our variables with API keys for OpenAI and E2B."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "# TODO: Get your OpenAI API key from https://platform.openai.com/api-keys\n",
    "os.environ[\"OPENAI_API_KEY\"] = \"\"\n",
    "\n",
    "# TODO: Get your E2B API key from https://e2b.dev/docs\n",
    "os.environ[\"E2B_API_KEY\"] = \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 3: Implement the method for code interpreting\n",
    "\n",
    "Here's the tool definition that uses the E2B code interpreter SDK. We'll be using this to get the E2B code interpreter tool and to format the output of the tool."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "\n",
    "from typing import Any, List\n",
    "from langchain_core.tools import Tool\n",
    "from pydantic.v1 import BaseModel, Field\n",
    "from e2b_code_interpreter import Sandbox\n",
    "from langchain_core.messages import BaseMessage, ToolMessage\n",
    "from langchain.agents.output_parsers.tools import (\n",
    "    ToolAgentAction,\n",
    ")\n",
    "\n",
    "\n",
    "class LangchainCodeInterpreterToolInput(BaseModel):\n",
    "    code: str = Field(description=\"Python code to execute.\")\n",
    "\n",
    "\n",
    "class CodeInterpreterFunctionTool:\n",
    "    \"\"\"\n",
    "    This class calls arbitrary code against a Python Jupyter notebook.\n",
    "    It requires an E2B_API_KEY to create a sandbox.\n",
    "    \"\"\"\n",
    "\n",
    "    tool_name: str = \"code_interpreter\"\n",
    "\n",
    "    def __init__(self):\n",
    "        # Instantiate the E2B sandbox - this is a long lived object\n",
    "        # that's pinging E2B cloud to keep the sandbox alive.\n",
    "        if \"E2B_API_KEY\" not in os.environ:\n",
    "            raise Exception(\n",
    "                \"Code Interpreter tool called while E2B_API_KEY environment variable is not set. Please get your E2B api key here https://e2b.dev/docs and set the E2B_API_KEY environment variable.\"\n",
    "            )\n",
    "        self.code_interpreter = Sandbox()\n",
    "\n",
    "    def call(self, parameters: dict, **kwargs: Any):\n",
    "        code = parameters.get(\"code\", \"\")\n",
    "        print(f\"***Code Interpreting...\\n{code}\\n====\")\n",
    "        execution = self.code_interpreter.run_code(code)\n",
    "        return {\n",
    "            \"results\": execution.results,\n",
    "            \"stdout\": execution.logs.stdout,\n",
    "            \"stderr\": execution.logs.stderr,\n",
    "            \"error\": execution.error,\n",
    "        }\n",
    "\n",
    "    def close(self):\n",
    "        self.code_interpreter.kill()\n",
    "\n",
    "    # langchain does not return a dict as a parameter, only a code string\n",
    "    def langchain_call(self, code: str):\n",
    "        return self.call({\"code\": code})\n",
    "\n",
    "    def to_langchain_tool(self) -> Tool:\n",
    "        tool = Tool(\n",
    "            name=self.tool_name,\n",
    "            description=\"Execute python code in a Jupyter notebook cell and returns any rich data (eg charts), stdout, stderr, and error.\",\n",
    "            func=self.langchain_call,\n",
    "        )\n",
    "        tool.args_schema = LangchainCodeInterpreterToolInput\n",
    "        return tool\n",
    "\n",
    "    @staticmethod\n",
    "    def format_to_tool_message(\n",
    "        agent_action: ToolAgentAction,\n",
    "        observation: dict,\n",
    "    ) -> List[BaseMessage]:\n",
    "        \"\"\"\n",
    "        Format the output of the CodeInterpreter tool to be returned as a ToolMessage.\n",
    "        \"\"\"\n",
    "        new_messages = list(agent_action.message_log)\n",
    "\n",
    "        # TODO: Add info about the results for the LLM\n",
    "        content = json.dumps(\n",
    "            {k: v for k, v in observation.items() if k not in (\"results\")}, indent=2\n",
    "        )\n",
    "        new_messages.append(\n",
    "            ToolMessage(content=content, tool_call_id=agent_action.tool_call_id)\n",
    "        )\n",
    "\n",
    "        return new_messages"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 4: Implement the methods for formatting messages, create and invoke the LangChain agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `code_interpreter` with `{'code': \"import matplotlib.pyplot as plt\\nimport numpy as np\\n\\nx = np.linspace(0, 2*np.pi, 100)\\ny = np.sin(x)\\n\\nplt.plot(x, y)\\nplt.title('Sine Wave')\\nplt.xlabel('x')\\nplt.ylabel('sin(x)')\\nplt.grid(True)\\nplt.show()\"}`\n",
      "\n",
      "\n",
      "\u001b[0m***Code Interpreting...\n",
      "import matplotlib.pyplot as plt\n",
      "import numpy as np\n",
      "\n",
      "x = np.linspace(0, 2*np.pi, 100)\n",
      "y = np.sin(x)\n",
      "\n",
      "plt.plot(x, y)\n",
      "plt.title('Sine Wave')\n",
      "plt.xlabel('x')\n",
      "plt.ylabel('sin(x)')\n",
      "plt.grid(True)\n",
      "plt.show()\n",
      "====\n",
      "\u001b[36;1m\u001b[1;3m{'results': [<e2b_code_interpreter.models.Result object at 0x11a267d90>], 'stdout': [], 'stderr': [], 'error': None}\u001b[0m\u001b[32;1m\u001b[1;3mHere is a plot of the sine wave.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<e2b_code_interpreter.models.Result at 0x11a267d90>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from typing import List, Sequence, Tuple\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain.agents import AgentExecutor\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.messages import BaseMessage\n",
    "from langchain_core.runnables import RunnablePassthrough\n",
    "from langchain.agents.output_parsers.tools import (\n",
    "    ToolAgentAction,\n",
    "    ToolsAgentOutputParser,\n",
    ")\n",
    "\n",
    "def format_to_tool_messages(\n",
    "    intermediate_steps: Sequence[Tuple[ToolAgentAction, dict]],\n",
    ") -> List[BaseMessage]:\n",
    "    messages = []\n",
    "    for agent_action, observation in intermediate_steps:\n",
    "        if agent_action.tool == CodeInterpreterFunctionTool.tool_name:\n",
    "            new_messages = CodeInterpreterFunctionTool.format_to_tool_message(\n",
    "                agent_action,\n",
    "                observation,\n",
    "            )\n",
    "            messages.extend([new for new in new_messages if new not in messages])\n",
    "        else:\n",
    "            # Handle other tools\n",
    "            print(\"Not handling tool: \", agent_action.tool)\n",
    "\n",
    "    return messages\n",
    "\n",
    "\n",
    "# 1. Pick your favorite llm\n",
    "llm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", temperature=0)\n",
    "\n",
    "# 2. Initialize the code interpreter tool\n",
    "code_interpreter = CodeInterpreterFunctionTool()\n",
    "code_interpreter_tool = code_interpreter.to_langchain_tool()\n",
    "tools = [code_interpreter_tool]\n",
    "\n",
    "\n",
    "# 3. Define the prompt\n",
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [(\"human\", \"{input}\"), (\"placeholder\", \"{agent_scratchpad}\")]\n",
    ")\n",
    "\n",
    "# 4. Define the agent\n",
    "agent = (\n",
    "    RunnablePassthrough.assign(\n",
    "        agent_scratchpad=lambda x: format_to_tool_messages(x[\"intermediate_steps\"])\n",
    "    )\n",
    "    | prompt\n",
    "    | llm.bind_tools(tools)\n",
    "    | ToolsAgentOutputParser()\n",
    ")\n",
    "\n",
    "agent_executor = AgentExecutor(\n",
    "    agent=agent,\n",
    "    tools=tools,\n",
    "    verbose=True,\n",
    "    return_intermediate_steps=True,\n",
    ")\n",
    "\n",
    "# 5. Invoke the agent\n",
    "result = agent_executor.invoke({\"input\": \"plot and show sinus\"})\n",
    "\n",
    "code_interpreter.kill()\n",
    "\n",
    "# Each intermediate step is a Tuple[ToolAgentAction, dict]\n",
    "result[\"intermediate_steps\"][0][1][\"results\"][0]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
